﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace inf_1007_devoir3
{
    public class Location
    {
        private static double DEPOT_GARANTIE = 200;
        private static int KILOMETRAGE_PAR_JOUR = 50;
        private static double MONTANT_KILOMETRAGE = 2;
        private Client client;
        private Vehicule vehicule;
        private DateTime dateDebut;
        private DateTime dateFin;
        private DateTime dateRetour;
        private int kilometrageDepart;
        private int kilometrageFin;
        private double montantPaye;
        private bool contratSigne;
        private double montantDegats;
        private string descriptionDegats;

        public Location()
        { }

        public Location(Client client, Vehicule vehicule, DateTime dateDebut, DateTime dateFin, int kilometrageDepart)
        {
            this.client = client;
            this.vehicule = vehicule;
            this.dateDebut = dateDebut;
            this.dateFin = dateFin;
            this.kilometrageDepart = kilometrageDepart;
        }


        public int nombreDeJours()
        {
            return (dateFin - dateDebut).Days;
        }

        public double montantLocationParJour()
        {
            return vehicule.getModele().getCoutLocation();
        }

        public double depotGarantie()
        {
            return DEPOT_GARANTIE;
        }

        public double calculSousTotalLocation()
        {
            return montantLocationParJour() * nombreDeJours();
        }

        public double calculMontantTPS()
        {
            return Taxes.montantTPS(calculSousTotalLocation());
        }

        public double calculMontantTVQ()
        {
            return Taxes.montantTVQ(calculSousTotalLocation());
        }

        public double calculMontantTotal()
        {
            return calculSousTotalLocation() + calculMontantTPS() + calculMontantTVQ() + depotGarantie() - montantPaye;
        }

        public Client getClient()
        {
            return client;
        }

        public Vehicule getVehicule()
        {
            return vehicule;
        }

        public DateTime getDateDebut()
        {
            return dateDebut;
        }

        public DateTime getDateFin()
        {
            return dateFin;
        }

        public DateTime getDateRetour()
        {
            return dateRetour;
        }

        public int getKilometrageDepart()
        {
            return kilometrageDepart;
        }

        public double getMontantPaye()
        {
            return montantPaye;
        }

        public string[] getLigneListe()
        {
            return new string[] { 
                client.ToString(),
                vehicule.ToString(),
                dateDebut.ToShortDateString(),
                dateFin.ToShortDateString(),
                dateRetour.ToShortDateString()
            };
        }

        public void payer(double montant, bool contratSigne,Location oldLoc)
        {
            montantPaye += montant;
            this.contratSigne = contratSigne;

            if (!existeDansListe())
            {
                CtrlLocation.getInstance().ajouterLocation(this);
            }
            else
            {
                oldLoc.vehicule.supprimerLocation(this);
                oldLoc.client.supprimerLocation(this);
            }

            vehicule.ajouterLocation(this);
            client.ajouterLocation(this);
            vehicule.setKilometrage(kilometrageDepart);
        }

        private bool existeDansListe()
        {
            return CtrlLocation.getInstance().existeDansListe(this);
        }

        public void copier(Location loc)
        { 
            loc.client = client;
            loc.vehicule = vehicule;
            loc.dateDebut = dateDebut;
            loc.dateFin = dateFin;
            loc.dateRetour = dateRetour;
            loc.kilometrageDepart = kilometrageDepart;
            loc.kilometrageFin = kilometrageFin;
            loc.montantPaye = montantPaye;
            loc.contratSigne = contratSigne;
            loc.montantDegats = montantDegats;
            loc.descriptionDegats = descriptionDegats;
        }

        public void supprimer()
        {
            vehicule.supprimerLocation(this);
            client.supprimerLocation(this);
            CtrlLocation.getInstance().supprimerLocation(this);
        }

        public void retourner(double montantDegats, string descriptionDegats, int kilometrage)
        {
            kilometrageFin = kilometrage;
            this.montantDegats = montantDegats;
            this.descriptionDegats = descriptionDegats;
            dateRetour = DateTime.Now;
        }

        public int getKilometrageTotal()
        {
            return kilometrageFin - kilometrageDepart;
        }

        public int getKilometrageInclus()
        {
            return nombreDeJours() * KILOMETRAGE_PAR_JOUR;
        }

        public int getKilometrageSurplus()
        {
            int surplus = getKilometrageTotal() - getKilometrageInclus();

            return (surplus < 0) ? 0 : surplus;
        }

        public double getMontantKilometrageSurplus()
        {
            return getKilometrageSurplus() * MONTANT_KILOMETRAGE;
        }

        public double calculTPSRetour()
        {
            return Taxes.montantTPS(getMontantKilometrageSurplus() + getMontantDegats());
        }

        public double calculTVQRetour()
        {
            return Taxes.montantTVQ(getMontantKilometrageSurplus() + getMontantDegats());
        }

        public double calculMontantTotalRetour()
        {
            return Taxes.montantAvecTaxes(getMontantKilometrageSurplus() + getMontantDegats()) - DEPOT_GARANTIE;
        }

        public double getMontantDegats()
        {
            return montantDegats;
        }

        public void payerRetour()
        {
            montantPaye += calculMontantTotalRetour();
        }
    }
}